package com.vvlive.caibao.smartcity.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 异步加载图片
 * 
 * @author zhj
 * 
 */
public class ImageAsyncLoader {
    private HashMap<String, SoftReference<Drawable>> cacheMap = null;
    private BlockingQueue<Runnable> queue = null;
    private ThreadPoolExecutor executor = null;

    public ImageAsyncLoader() {
        cacheMap = new HashMap<String, SoftReference<Drawable>>();

        queue = new LinkedBlockingQueue<Runnable>();
        /**
         * 线程池维护线程的最少数量2 <br>
         * 线程池维护线程的最大数量10<br>
         * 线程池维护线程所允许的空闲时间180秒
         */
        executor = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, queue);
    }

    @SuppressLint("HandlerLeak") public Drawable loadDrawable(final Context context, final String imageUrl, final ImageCallback imageCallback) {
        if (cacheMap.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = cacheMap.get(imageUrl);
            Drawable drawable = softReference.get();
            if (drawable != null) {
                return drawable;
            }
        }

        final Handler handler = new Handler() {
            public void handleMessage(Message message) {
                imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
            }
        };

        // 将任务添加到线程池
        executor.execute(new Runnable() {
            public void run() {
                // 根据URL加载图片
                Drawable drawable = loadImageFromUrl(context, imageUrl);

                // 图片资源不为空是创建软引用
                if (null != drawable)
                    cacheMap.put(imageUrl, new SoftReference<Drawable>(drawable));

                Message message = handler.obtainMessage(0, drawable);
                handler.sendMessage(message);
            }
        });

        return null;
    }

    // 网络图片先下载到本地cache目录保存，以imagUrl的图片文件名保存，如果有同名文件在cache目录就从本地加载
    public static Drawable loadImageFromUrl(Context context, String imageUrl) {
        Drawable drawable = null;

        if (imageUrl == null)
            return null;
        String fileName = "";

        // 获取url中图片的文件名与后缀
        if (imageUrl != null && imageUrl.length() != 0) {
            fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
        }

        // 根据图片的名称创建文件（不存在：创建）
        File file = new File(context.getCacheDir(), fileName);

        // 如果在缓存中找不到指定图片则下载
        if (!file.exists() && !file.isDirectory()) {
            try {
                // 从网络上下载图片并写入文件
                FileOutputStream fos = new FileOutputStream(file);
                InputStream is = new URL(imageUrl).openStream();
                int data = is.read();
                while (data != -1) {
                    fos.write(data);
                    data = is.read();
                }
                fos.close();
                is.close();

                drawable = Drawable.createFromPath(file.toString());    // 从本地路径创建Drawable
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 如果缓存中有则直接使用缓存中的图片
        else {
            // System.out.println(file.isDirectory() + " " + file.getName());
            drawable = Drawable.createFromPath(file.toString());
        }
        return drawable;
    }

    public interface ImageCallback {
        void imageLoaded(Drawable imageDrawable, String imageUrl);
    }


    //常用图片处理方法：

    /**
     * 缩放Drawable
     *
     * @param drawable
     * @param w        缩放后的宽
     * @param h        缩放后的高
     * @return Drawable
     */
    @SuppressWarnings("deprecation")
	public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        // drawable转换成bitmap
        Bitmap oldbmp = drawableToBitmap(drawable);
        // 创建操作图片用的Matrix对象
        Matrix matrix = new Matrix();
        // 计算缩放比例
        float scaleWidth = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidth, scaleHeight);
        // 设置缩放比例
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
        return new BitmapDrawable(newbmp);
    }

    /**
     * 将drawable转换成bitmap
     *
     * @param drawable
     * @return Bitmap
     */
    private static Bitmap drawableToBitmap(Drawable drawable) {
        // 取drawable的长宽
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; // 取drawable的颜色格式

        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * 单位转换：dip => px
     *
     * @param ctx      上下文环境
     * @param dipValue
     * @return
     */
    public static int dip2px(Context ctx, int dipValue) {
        final float scale = ctx.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale);

    }
}